import React from 'react';
import { Upload, message, Icon, Spin } from 'antd';
import upImg from './upload.png';
import fileImg from './file.png';
import ImgPreview from '../ImgPreview';
import beforeUpload from './beforeUpload';
import uploadUrl from './uploadUrl';
import less from './index.less';

/** 常用props
 * uploadImg 上传按钮图片
 * typeImg 上传图片类型文件
 * className 通过class样式设置宽高
 * maxSize 最大文件多少M
 * multiple 最多可以上传几个文件
 */
class UploadFile extends React.Component {
  constructor(props) {
    super(props);

    this.state = {
      value: props.value,
      currentFile: 0,
      preview: false,
      loading: false,
    };
  }

  static getDerivedStateFromProps(nextProps, prevState) {
    if ('value' in nextProps) {
      return { value: nextProps.value };
    }
    return null;
  }

  onRemove = index => {
    if (this.props.multiple) {
      const { value } = this.state;
      value.splice(index, 1);
      this.triggerChange([...value]);
    }
  };

  handleChange = info => {
    const { name: FileName, size: FileSize } = info.file;
    if (info.file.status === 'uploading') {
      this.setState({ loading: true });
    } else {
      this.setState({ loading: false });
    }
    if (info.file.status === 'done') {
      if (info.file.response && info.file.response.SuccessResponse) {
        message.success(`${info.file.name} 文件上传成功`);
        let value = this.state.value || [];
        if (this.props.multiple) {
          if (value.length < this.props.multiple) {
            value = [
              ...value,
              {
                FileName,
                FileSize,
                URL: info.fileList[info.fileList.length - 1].response.Data.Url,
              },
            ];
          }
        } else {
          value = {
            FileName,
            FileSize,
            URL: info.file.response.Data.Url,
          };
        }
        this.triggerChange(value);
      } else {
        info.fileList.splice(0, 1);
        message.error(
          `${info.file.name} 文件上传失败.${info.file.response.Message}`,
        );
      }
    } else if (info.file.status === 'error') {
      message.error(`${info.file.name} 文件上传失败.`);
    }
  };

  handlePreviewEvent = (currentFile, URL) => e => {
    e.stopPropagation();
    if (this.props.typeImg) {
      this.setState({
        preview: true,
        currentFile,
      });
    } else {
      window.open(URL);
    }
  };

  triggerChange = changedValue => {
    this.setState({ value: changedValue });
    const { onChange } = this.props;
    if (onChange) {
      onChange(changedValue);
    }
  };

  renderChild = value => {
    const { uploadImg = upImg } = this.props;
    if (!this.props.multiple && value) {
      return (
        <div className={`${less.preview} g-flex-cc`}>
          {this.renderFile(value)}
          <div className="img-tool">
            <span className="img-tool-item">
              <Icon
                type="eye"
                onClick={this.handlePreviewEvent(0, value.URL)}
              />
            </span>
          </div>
        </div>
      );
    }
    return <img src={uploadImg} className={less.imgCenter} alt="默认文件" />;
  };

  closePreview = () => {
    this.setState({ preview: false });
  };

  renderFile = v => {
    const { typeImg, uploadImg = upImg } = this.props;
    if (typeImg) {
      return (
        <img
          src={v.URL || uploadImg}
          className={less.imgCenter}
          alt="上传的文件"
        />
      );
    }
    return (
      <div className="absolute g-full" style={{ textAlign: 'center' }}>
        <img src={fileImg} />
        <div className="text-overflow">{v.FileName}</div>
      </div>
    );
  };

  render() {
    const {
      options,
      renderOption,
      maxSize = 2,
      uploadImg,
      value: val,
      className = less.imgSize,
      typeImg,
      ...others
    } = this.props;
    const { value, loading } = this.state;
    const accept = typeImg ? 'image/jpg, image/jpeg, image/png' : others.accept;
    const props1 = {
      name: 'file',
      action: uploadUrl,
      multiple: !!this.props.multiple,
      showUploadList: false,
      listType: 'picture-card',
      accept,
      beforeUpload: beforeUpload({
        accept,
        maxSize,
      }),
    };

    const images = this.props.multiple
      ? (value || []).map(v => ({ src: v.URL }))
      : [{ src: value && value.URL }];
    return (
      <div className={less.uploadImg}>
        {!!this.props.multiple &&
          value &&
          value.map((v, i) => (
            <span
              key={v.URL}
              className={className}
              style={{
                display: 'inline-block',
                marginRight: '10px',
                verticalAlign: 'top',
                border: '1px dashed #eee',
              }}
            >
              <div className={`g-flex-cc ${less.preview}`}>
                {this.renderFile(v)}
                <div className="img-tool">
                  <span className="img-tool-item">
                    <Icon
                      type="eye"
                      className={!others.disabled && 'margin-right'}
                      onClick={this.handlePreviewEvent(i, v.URL)}
                    />
                    {!others.disabled && (
                      <Icon type="delete" onClick={() => this.onRemove(i)} />
                    )}
                  </span>
                </div>
              </div>
            </span>
          ))}

        {!others.disabled &&
          !(
            this.props.multiple &&
            value &&
            this.props.multiple <= value.length
          ) && (
            <Upload
              className={className}
              {...props1}
              {...others}
              onChange={this.handleChange}
              disabled={loading}
            >
              <Spin spinning={loading}>{this.renderChild(value)}</Spin>
            </Upload>
          )}

        {others.disabled && !this.props.multiple && (
          <div className={`${className} relative`}>
            {this.renderChild(value)}
          </div>
        )}

        {typeImg && (
          <ImgPreview
            currentFile={this.state.currentFile}
            images={images}
            width={1200}
            hasRotate
            visible={this.state.preview}
            onClose={this.closePreview}
          />
        )}
      </div>
    );
  }
}

export default UploadFile;
